package com.ccf.business.etl.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.common.utils.constant.Constants;
import com.ccf.business.etl.mapper.JobMapper;
import com.ccf.business.etl.mapper.TaskMapper;
import com.ccf.business.etl.model.FlowLog;
import com.ccf.business.etl.model.Job;
import com.ccf.business.etl.model.Task;
import com.ccf.business.etl.model.vo.JobVO;
import com.ccf.business.etl.model.vo.ScheduleCountVO;
import com.ccf.business.etl.model.vo.TopTenCountVO;
import com.ccf.business.etl.service.IFlowLogService;
import com.ccf.business.etl.service.IJobService;
import com.common.model.pojo.Query;
import com.common.model.result.CodeEnum;
import com.common.model.result.PageResult;
import com.service.mybatis.service.impl.SuperServiceImpl;
import com.service.mybatis.util.Condition;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 任务运行实例表
 *
 * @author zhaoj
 * @date 2021-12-01 15:15:53
 */
@Slf4j
@Service
public class JobServiceImpl extends SuperServiceImpl<JobMapper, Job> implements IJobService {

    @Autowired
    private IFlowLogService flowLogService;

    @Autowired
    private TaskMapper taskMapper;

    /**
    * 列表
    * @param query
    * @return
    */
    @Override
    public PageResult<JobVO> findList(Query query){
        Page<Job> page = page(Condition.getPage(query), Condition.getQueryWrapper(query));
        List<JobVO> collect = page.getRecords().stream().map(Job::toVo).peek(job -> {
            if(ObjectUtil.isNotNull(job.getElapsedTime())) {
                job.setFormatElapsedTime(DateUtil.formatBetween(job.getElapsedTime()));
            }
        }).collect(Collectors.toList());
        return PageResult.<JobVO>builder().datas(collect).code(CodeEnum.SUCCESS.getCode()).count(page.getTotal()).build();
    }

    @Override
    public List<ScheduleCountVO> runningCountDay(String day) {
        //根据传入的day获取开始时间结束时间
        int dayOffset = Convert.toInt(day);
        String startTime = DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), -dayOffset).toJdkDate()).toString();
        String endTime = DateUtil.endOfDay(new Date()).toString();

        //查询数据
        List<Map> results = baseMapper.countJobRunning(startTime, endTime);
        //将数据转换成Map对象
        Map<String, Integer> resultMap = results.stream().collect(Collectors.toMap(row -> row.get("date").toString() + row.get("status").toString(), row -> Convert.toInt(row.get("count"))));


        //根据天数生成返回对象
        List<ScheduleCountVO> vos = new ArrayList<>();
        for (int i=dayOffset; i >= 0; i --) {
            String date = DateUtil.formatDate(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), -i).toJdkDate()));

            ScheduleCountVO scheduleCountVo = ScheduleCountVO.builder()
                    .date(date)
                    .failCount(resultMap.getOrDefault(date + Task.STATUS_FAIL, 0))
                    .runningCount(resultMap.getOrDefault(date + Task.STATUS_RUNNING, 0))
                    .finishCount(resultMap.getOrDefault(date + Task.STATUS_FINISH, 0))
                    .watingCount(resultMap.getOrDefault(date + Task.STATUS_WAITTING, 0))
                    .build();

            vos.add(scheduleCountVo);
        }

        return vos;
    }

    @Override
    public List<TopTenCountVO> runningTimeCountStatus(String status) {
        //取30天开始结束日期
        String startTime = DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), -30).toJdkDate()).toString();
        String endTime = DateUtil.endOfDay(new Date()).toString();

        //如果查询全部则置空
        if(Constants.ALL.equals(status)) {
            status = Constants.EMPTY;
        }

        List<TopTenCountVO> results = baseMapper.runningTimeCountStatus(startTime, endTime, status);
        return results;
    }

    @Override
    public JobVO detail(String id) {
        Job job = this.getById(id);
        JobVO jobVO = job.toVo();

        List<FlowLog> logs = flowLogService.list(Wrappers.<FlowLog>lambdaQuery().eq(FlowLog::getFlowId, job.getId()).orderByAsc(FlowLog::getLogId));
        List<String> logStrs = logs.stream().map(FlowLog::toString).collect(Collectors.toList());
        jobVO.setLogs(logStrs);

        return jobVO;
    }

    @Override
    public List<Job> getJobByFlowIds(Set<String> ids) {
        LambdaQueryWrapper<Job> eq = Wrappers.<Job>lambdaQuery()
                .in(CollUtil.isNotEmpty(ids), Job::getFlowId, ids);
        List<Job> list = list(eq);
        return list;
    }
}
